<template>
	<main class="main-page" id="">
		<template v-if="showHeader">
			<section class="page-section mb-3">
				<div class="container-fluid">
					<div class="grid justify-content-between align-items-center">
						<div class="col ">
							<div class=" text-2xl text-primary font-bold">
								{{ $t('grades') }}
							</div>
						</div>
						<div class="col-fixed ">
							<template v-if="auth.canView('grades/add')">
								<router-link :to="`/grades/add`">
									<Button :label="$t('addNewGrade')" icon="pi pi-plus" type="button"
										class="p-button w-full bg-primary " />
								</router-link>
							</template>
						</div>
						<div class="col-fixed ">
							<template v-if="auth.canView('grades/bulk-import')">
								<Button :label="$t('downloadTemplate')" icon="pi pi-download" type="button"
									class="p-button w-full bg-primary ml-2" @click="downloadTemplate" />
							</template>
						</div>
						<div class="col-fixed ">
							<template v-if="auth.canView('grades/bulk-import')">
								<Button :label="$t('importGrades')" icon="pi pi-upload" type="button"
									class="p-button w-full bg-primary ml-2" @click="showImportDialog = true" />
							</template>
						</div>
						<div class="col-12 md:col-3 ">
							<span class="p-input-icon-left w-full">
								<i class="pi pi-search" />
								<InputText :placeholder="$t('search')" class="w-full" :value="filters.search.value"
									@input="debounce(() => { filters.search.value = $event.target.value })" />
							</span>
						</div>

					</div>
				</div>
			</section>
		</template>
		<section class="page-section ">
			<div class="container-fluid">
				<div class="grid ">
					<div class="col comp-grid">
						<div class="flex align-items-center">
							<filter-tags :controller="page.filterController" />
						</div>
						<div>
							<template v-if="showBreadcrumbs && $route.query.tag && !isSubPage">
								<Breadcrumb :home="{ icon: 'pi pi-home', to: '/grades' }" :model="pageBreadCrumb" />
							</template>
							<!-- page records template -->
							<div class="student-list">
								<div v-for="student in records" :key="student.name" class="student-card">
									<div class="student-header">
										<image-viewer image-size="small" image-preview-size="" :src="student.avatar_url"
											width="50px" height="50px" class="img-fluid" :num-display="1">
										</image-viewer>
										<div class="student-info">
											<h3>{{ student.name }}</h3>
											<span v-if="student.personnel_id" class="student-id">学号: {{
												student.personnel_id
											}}</span>
										</div>
									</div>

									<!-- 学生成绩表格 -->
									<Panel :toggleable="true" :collapsed="true" class="mb-3">
										<template #header>
											<div class="flex align-items-center gap-2">
												<i class="pi pi-table"></i>
												<span>查看成绩表格</span>
											</div>
										</template>
										<DataTable :value="student.grades" class="p-datatable-sm" stripedRows>
											<Column field="course_name" header="课程名称"></Column>
											<Column field="daily_grade" header="平时成绩">
												<template #body="{data}">
													{{ data.daily_grade || '-' }}
												</template>
											</Column>
											<Column field="exam_grade" header="考试成绩">
												<template #body="{data}">
													{{ data.exam_grade || '-' }}
												</template>
											</Column>
											<Column field="homework_grade" header="作业成绩">
												<template #body="{data}">
													{{ data.homework_grade || '-' }}
												</template>
											</Column>
											<Column field="final_grade" header="最终成绩">
												<template #body="{data}">
													{{ data.final_grade || '-' }}
												</template>
											</Column>
											<Column field="teacher_feedback" header="教师评语">
												<template #body="{data}">
													{{ data.teacher_feedback || '-' }}
												</template>
											</Column>
											<Column field="semester_name" header="学期">
												<template #body="{data}">
													{{ data.semester_name || '-' }}
												</template>
											</Column>
											<Column field="teacher_signature" header="教师签名">
												<template #body="{data}">
													<span v-if="data.teacher_signature" class="signature">
														{{ data.teacher_signature.slice(0, 10) }}...{{
															data.teacher_signature.slice(-10) }}
													</span>
													<span v-else class="text-gray-500">
														未签名
													</span>
												</template>
											</Column>
											<Column header="操作" :exportable="false">
												<template #body="{data}">
													<Button 
														v-if="data.teacher_signature" 
														label="验证签名" 
														icon="pi pi-verified" 
														class="p-button-sm p-button-text"
														@click="verifySignature(data)"
													/>
												</template>
											</Column>
										</DataTable>
									</Panel>
								</div>
							</div>
			
							<!-- Empty record -->
							<template v-if="pageReady && !records.length">
								<div class="p-3 my-3 text-500 text-lg font-medium text-center">
									{{ $t('noRecordFound') }}
								</div>
							</template>
							<!-- end of empty record-->
							<!-- pagination component-->
							<template v-if="showFooter && pageReady">
								<div class="grid justify-content-between align-items-center">
									<div class="flex gap-2 flex-grow-0">
										<template v-if="auth.canView('grades')">
											<div v-if="selectedItems.length" class="m-2">
												<Button @click="deleteItem(selectedItems)" icon="pi pi-trash"
													class="p-button-danger" :title="$t('deleteSelected')" />
											</div>
										</template>
									</div>
									<div v-if="paginate && totalPages > 1" class="flex-grow-1">
										<Paginator class="paginator-flat my-3" :first="recordsPosition - 1"
											@page="(event) => { pagination.page = event.page + 1 }"
											:rows="pagination.limit" :totalRecords="totalRecords">
											<template #start>
												<span class="px-2">
													{{ $t('records') }} <b>{{ recordsPosition }} {{ $t('of') }} {{
														totalRecords }}</b>
												</span>
											</template>
											<template #end>
											</template>
										</Paginator>
									</div>
								</div>
							</template>
							<Dialog v-model:visible="showImportDialog" :style="{ width: '50vw' }"
								:header="$t('importGrades')" :modal="true">
								<FileUpload name="file" mode="basic" @select="onFileSelect" :multiple="false"
									accept=".xlsx,.xls" :maxFileSize="1000000" chooseLabel="选择文件" :auto="false"
									:showUploadButton="false" :showCancelButton="false" dropMessage="将文件拖放到此处上传">
								</FileUpload>

								<DataTable :value="importData" v-if="importData.length" class="mt-3">
									<Column field="enrollment_id" header="选课ID"></Column>
									<Column field="course_name" header="课程名称"></Column>
									<Column field="daily_grade" header="平时成绩"></Column>
									<Column field="exam_grade" header="考试成绩"></Column>
									<Column field="homework_grade" header="作业成绩"></Column>
									<Column field="final_grade" header="最终成绩"></Column>
									<Column field="teacher_feedback" header="教师反馈"></Column>
									<Column field="last_updated" header="最后更新时间"></Column>
									<Column field="updated_by" header="更新人"></Column>
									<Column field="semester_name" header="学年"></Column>

									<Column field="teacher_signature" header="教师签名">
										<template #body="{ data }">
											<span v-if="data.teacher_signature" class="signature">
												{{ data.teacher_signature.slice(0, 10) }}...{{
													data.teacher_signature.slice(-10) }}
											</span>
											<span v-else-if="data.error" class="text-red-500">
												签名失败: {{ data.error }}
											</span>
											<span v-else class="text-gray-500">
												未签名
											</span>
										</template>
									</Column>

								</DataTable>

								<template #footer>
									<Button :label="$t('cancel')" icon="pi pi-times" @click="showImportDialog = false"
										class="p-button-text" />
									<Button :label="$t('confirmImport')" icon="pi pi-check" @click="confirmImport"
										:disabled="!importData.length" />
								</template>
							</Dialog>
							<!-- end of pagination component-->
						</div>
					</div>
				</div>
			</div>
		</section>
	</main>

	<!-- 添加验证成绩对话框 -->
	<Dialog v-model:visible="showVerifyDialog" :style="{ width: '50vw' }" 
		:header="$t('verifyGrade')" :modal="true">
		<div class="verify-content">
			<div class="verify-item">
				<label>课程名称：</label>
				<span>{{ selectedGrade?.course_name }}</span>
			</div>
			<div class="verify-item">
				<label>平时成绩：</label>
				<span>{{ selectedGrade?.daily_grade || '-' }}</span>
			</div>
			<div class="verify-item">
				<label>考试成绩：</label>
				<span>{{ selectedGrade?.exam_grade || '-' }}</span>
			</div>
			<div class="verify-item">
				<label>作业成绩：</label>
				<span>{{ selectedGrade?.homework_grade || '-' }}</span>
			</div>
			<div class="verify-item">
				<label>最终成绩：</label>
				<span>{{ selectedGrade?.final_grade || '-' }}</span>
			</div>
			<div class="verify-item">
				<label>学期：</label>
				<span>{{ selectedGrade?.semester_name || '-' }}</span>
			</div>
			<div class="verify-item">
				<label>教师评语：</label>
				<span>{{ selectedGrade?.teacher_feedback || '-' }}</span>
			</div>
		</div>
		<template #footer>
			<Button :label="$t('cancel')" icon="pi pi-times" @click="showVerifyDialog = false"
				class="p-button-text" />
			<Button :label="$t('verify')" icon="pi pi-check" @click="confirmVerify" />
		</template>
	</Dialog>
</template>
<script setup>
import { toRefs, onMounted, ref } from 'vue';
import { ApiService } from 'src/services/api';
import * as XLSX from 'xlsx';
import { usePageStore } from 'src/store/page';
import { useApp } from 'src/composables/app.js';
import { useAuth } from 'src/composables/auth';
import { $t } from 'src/services/i18n';
import { useListPage } from 'src/composables/listpage.js';
import { useToast } from 'primevue/usetoast';
import { signMessage, getAccounts } from '../../services/web3Service.js'

const props = defineProps({
	primaryKey: {
		type: String,
		default: 'grade_id',
	},
	pageStoreKey: {
		type: String,
		default: 'GRADES',
	},
	pageName: {
		type: String,
		default: 'grades',
	},
	routeName: {
		type: String,
		default: 'gradeslist',
	},
	apiPath: {
		type: String,
		default: 'grades/index',
	},
	autoLoad: {
		type: Boolean,
		default: true,
	},
	enableCache: {
		type: Boolean,
		default: false,
	},
	paginate: {
		type: Boolean,
		default: true,
	},
	showHeader: {
		type: Boolean,
		default: true,
	},
	showFooter: {
		type: Boolean,
		default: true,
	},
	showBreadcrumbs: {
		type: Boolean,
		default: true,
	},
	exportButton: {
		type: Boolean,
		default: true,
	},
	importButton: {
		type: Boolean,
		default: false,
	},
	multiCheckbox: {
		type: Boolean,
		default: true,
	},
	page: {
		type: Number,
		default: 1,
	},
	limit: {
		type: Number,
		default: 6,
	},
	mergeRecords: { // for infinite loading
		type: Boolean,
		default: false,
	},
	search: {
		type: String,
		default: '',
	},
	fieldName: null,
	fieldValue: null,
	queryParams: {
		type: Object,
		default: () => ({})
	},
	sortBy: {
		type: String,
		default: '',
	},
	sortType: {
		type: String,
		default: 'desc', //desc or asc
	},
	isSubPage: {
		type: Boolean,
		default: false,
	},
	emptyRecordMsg: {
		type: String,
		default: () => $t('noRecordFound'),
	},
	titleBeforeDelete: {
		type: String,
		default: $t('deleteRecord'),
	},
	msgBeforeDelete: {
		type: String,
		default: () => $t('promptDeleteRecord'),
	},
	msgAfterDelete: {
		type: String,
		default: () => $t('recordDeletedSuccessfully'),
	},
	filterTagClass: {
		type: String,
		default: 'surface-card p-2 text-500 flex-grow-1 text-center m-1 mb-3 flex-grow-1 text-center',
	}
});

const app = useApp();
const auth = useAuth();

const toast = useToast();

const showImportDialog = ref(false);
const importData = ref([]);
const showVerifyDialog = ref(false);
const selectedGrade = ref(null);

const account = ref('');



const onFileSelect = async (event) => {
	const file = event.files[0];
	const reader = new FileReader();

	reader.onload = async (e) => {
		try {
			const data = new Uint8Array(e.target.result);
			const workbook = XLSX.read(data, { type: 'array' });
			const sheet = workbook.Sheets[workbook.SheetNames[0]];
			const jsonData = XLSX.utils.sheet_to_json(sheet, { range: 1 });

			// 获取账户
			const accounts = await getAccounts();
			account.value = accounts[0];

			console.log(new Date(Date.now()))

			// 使用 Promise.all 处理所有异步签名
			const processedData = await Promise.all(jsonData.map(async (row) => {
				try {
					const signData = {
						course_name: row['course_name'],
						daily_grade: parseFloat(row['daily_grade']).toFixed(2), // 确保2位小数
						exam_grade: parseFloat(row['exam_grade']).toFixed(2),
						homework_grade: parseFloat(row['homework_grade']).toFixed(2),
						final_grade: parseFloat(row['final_grade']).toFixed(2),
						semester_name: row['semester_name'],
						teacher_feedback: row['teacher_feedback'],
					}

					// 将对象按键名排序后转为JSON字符串
					const sortedData = Object.keys(signData)
						.sort()
						.reduce((obj, key) => {
							obj[key] = signData[key];
							return obj;
						}, {});
					const messageToSign = JSON.stringify(sortedData, null, 0);

					const signature = await signMessage(messageToSign, account.value);

					return {
						enrollment_id: row['enrollment_id'],
						course_name: row['course_name'],
						daily_grade: row['daily_grade'],
						exam_grade: row['exam_grade'],
						homework_grade: row['homework_grade'],
						final_grade: row['final_grade'],
						teacher_feedback: row['teacher_feedback'],
						last_updated: new Date(Date.now()),
						updated_by: auth.user?.personnel_id || null,
						teacher_signature: signature,
						semester_name: row['semester_name']
					};
				} catch (error) {
					console.error('签名失败:', error);
					return {
						...row,
						teacher_signature: null,
						error: error.message
					};
				}
			}));

			importData.value = processedData;
		} catch (error) {
			console.error('文件处理错误:', error);
			toast.add({ severity: 'error', summary: '错误', detail: '文件处理失败', life: 3000 });
		}
	};

	reader.readAsArrayBuffer(file);
};

const confirmImport = async () => {
	try {
		await ApiService.post('grades/bulk-import', importData.value);
		showImportDialog.value = false;
		importData.value = [];
		toast.add({ severity: 'info', summary: '成功', detail: '文件上传成功', life: 3000 });
		load(); // 重新加载数据
	} catch (error) {
		toast.add({ severity: 'error', summary: '错误', detail: '文件上传失败', life: 3000 });
	}
};

const downloadTemplate = async () => {
	try {
		const response = await ApiService.get('grades/template', {
			responseType: 'arraybuffer' // 确保以二进制格式接收数据
		});
		const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
		const link = document.createElement('a');
		link.href = URL.createObjectURL(blob);
		link.download = 'grades_template.xlsx';
		document.body.appendChild(link);
		link.click();
		document.body.removeChild(link);
		URL.revokeObjectURL(link.href);
	} catch (error) {
		toast.add({ severity: 'error', summary: '错误', detail: '下载模板失败', life: 3000 });
	}
};


const defaultStoreState = {
	filters: {
		search: {
			tag: "Search",
			value: '',
			valueType: 'single',
			options: [],
		}
	},
	pagination: {
		page: props.page,
		limit: props.limit,
		sortBy: props.sortBy,
		sortType: props.sortType
	},
	primaryKey: props.primaryKey,
	enableCache: props.enableCache
}
const store = usePageStore(props.pageStoreKey, defaultStoreState);

// page hooks where logics resides
const page = useListPage({ store, props });

const { records, filters, totalRecords, selectedItems, pagination, } = toRefs(store.state);
const { pageReady, loading, } = toRefs(page.state);

const { pageBreadCrumb, totalPages, recordsPosition, } = page.computedProps;

const { load, exportPage, debounce, onSort, deleteItem, } = page.methods;



function getActionMenuModel(data) {
	return [
		{
			label: () => $t('view'),
			to: `/grades/view/${data.grade_id}`,
			icon: "pi pi-eye",
			visible: auth.canView('grades/view')
		},
		{
			label: () => $t('edit'),
			to: `/grades/edit/${data.grade_id}`,
			icon: "pi pi-pencil",
			visible: auth.canView('grades/edit')
		},
		{
			label: () => $t('delete'),
			command: (event) => { deleteItem(data.grade_id) },
			icon: "pi pi-trash",
			visible: auth.canView('grades/delete')
		}
	]
}

// 修改验证签名方法
const verifySignature = async (gradeData) => {
    selectedGrade.value = gradeData;
    showVerifyDialog.value = true;
};

// 添加确认验证方法
const confirmVerify = async () => {
    try {
        const response = await ApiService.post('grades/verify-signature', {
            course_name: selectedGrade.value.course_name,
            daily_grade: selectedGrade.value.daily_grade,
            exam_grade: selectedGrade.value.exam_grade,
            homework_grade: selectedGrade.value.homework_grade,
            final_grade: selectedGrade.value.final_grade,
            semester_name: selectedGrade.value.semester_name,
            teacher_feedback: selectedGrade.value.teacher_feedback,
            signature: selectedGrade.value.teacher_signature
        });

        const result = response.data;

        if (result.success) {
            toast.add({
                severity: 'success',
                summary: '验证成功',
                detail: `签名验证通过，教师: ${result.teacherName} (ID: ${result.teacherId})`,
                life: 5000
            });
        } else {
            toast.add({
                severity: 'error',
                summary: '验证失败',
                detail: result.message || '签名验证失败',
                life: 5000
            });
        }
    } catch (error) {
        console.error('验证签名时出错:', error);
        toast.add({
            severity: 'error',
            summary: '错误',
            detail: '验证签名时发生错误',
            life: 5000
        });
    } finally {
        showVerifyDialog.value = false;
    }
};

onMounted(async () => {
	const pageTitle = $t('grades');
	app.setPageTitle(props.routeName, pageTitle);
	const accounts = await getAccounts();
	account.value = accounts[0];

	console.log(records)

});
</script>
<style scoped>
.student-list {
	display: grid;
	gap: 1.5rem;
}

.student-card {
	background: var(--surface-card);
	border-radius: 10px;
	padding: 1.5rem;
	box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.student-header {
	display: flex;
	align-items: center;
	margin-bottom: 1.5rem;
	gap: 1rem;
}

.student-info {
	display: flex;
	flex-direction: column;
}

.student-info h3 {
	margin: 0;
	font-size: 1.2rem;
}

.student-id {
	color: var(--text-color-secondary);
	font-size: 0.9rem;
}

.grade-cards {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
	gap: 1rem;
}

.grade-card {
	background: var(--surface-ground);
	border-radius: 8px;
	padding: 1rem;
	border-left: 4px solid var(--primary-color);
}

.course-name {
	font-weight: 600;
	margin-bottom: 0.8rem;
	font-size: 1.1rem;
	color: var(--primary-color);
}

.grade-details {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 0.8rem;
	margin-bottom: 0.8rem;
}

.grade-item {
	display: flex;
	justify-content: space-between;
}

.grade-item.final {
	grid-column: span 2;
	font-weight: bold;
	color: var(--primary-color);
}

.teacher-feedback {
	font-size: 0.9rem;
	color: var(--text-color-secondary);
	margin-top: 0.5rem;
	padding-top: 0.5rem;
	border-top: 1px dashed var(--surface-border);
}

.semester {
	font-size: 0.8rem;
	color: var(--text-color-secondary);
	margin-top: 0.5rem;
}

.p-button-sm {
    font-size: 0.8rem;
    padding: 0.3rem 0.6rem;
}

.verify-content {
    padding: 1rem;
}

.verify-item {
    display: flex;
    margin-bottom: 1rem;
    padding: 0.5rem;
    border-bottom: 1px solid var(--surface-border);
}

.verify-item label {
    font-weight: 600;
    min-width: 100px;
    color: var(--text-color-secondary);
}

.verify-item span {
    flex: 1;
}
</style>

